<script setup>
import { Plus, Refresh, Delete, Upload, Download } from '@element-plus/icons-vue'
import { ref, onMounted } from 'vue'
import { ElMessage, ElMessageBox } from 'element-plus'
import { 
  addCheckIn, updateCheckIn, deleteCheckIn, batchDeleteCheckIn,
  checkout, transfer, getCheckInPage
} from '@/api/checkin'
import { getDormBuildingPage } from '@/api/dormBuilding'
import { getDormRoomPage, getDormRoomByBuilding } from '@/api/dormRoom'

onMounted(() => {
  loadBuildings()
  getData()
})

const loading = ref(false)
const tableData = ref([])
const pagination = ref({ currentPage: 1, pageSize: 10, total: 0 })
const selectedRows = ref([])
const multipleTableRef = ref()

const buildings = ref([])
const buildingOptions = ref([])
const roomOptions = ref([])
const buildingLabelMap = ref({})
const roomLabelMap = ref({})

const queryForm = ref({ studentId: '', buildingId: null, roomId: null, status: '' })

const dialogFormVisible = ref(false)
const title = ref('')
const formRef = ref(null)
const formData = ref({
  id: '',
  studentId: null,
  buildingId: null,
  roomId: null,
  bedNo: '',
  checkInDate: '',
  checkOutDate: '',
  operatorId: null,
  status: '入住中',
  remark: ''
})

const rules = {
  studentId: [{ 
    required: true, message: '请输入学生ID', trigger: 'blur' 
  }],
  
  buildingId: [{
     required: true, message: '请选择楼宇', trigger: 'change' }],
  roomId: [{ required: true, message: '请选择房间', trigger: 'change' 
  }],

  bedNo: [{
     required: true, message: '请输入床位号', trigger: 'blur' 
    }]
}

const loadBuildings = () => {
  getDormBuildingPage({ currentPage: 1, pageSize: 1000 }).then(res => {
    if (res.code === 200) {
      const page = res.data || {}
      buildings.value = page.list || []
      buildingOptions.value = buildings.value.map(b => ({ label: `${b.buildingNo}-${b.buildingName}` , value: b.id }))
      buildingLabelMap.value = Object.fromEntries(buildingOptions.value.map(o => [o.value, o.label]))
    }
  })
}

const loadRoomsByBuilding = (buildingId) => {
  if (!buildingId) { roomOptions.value = []; roomLabelMap.value = {}; return }
  getDormRoomByBuilding(buildingId).then(res => {
    if (res.code === 200) {
      const list = res.data || []
      roomOptions.value = list.map(r => ({ label: `${r.roomNo}（${r.roomStatus || '可用'}）`, value: r.id }))
      roomLabelMap.value = Object.fromEntries(roomOptions.value.map(o => [o.value, o.label]))
    }
  })
}

const getData = () => {
  loading.value = true
  getCheckInPage({ currentPage: pagination.value.currentPage, pageSize: pagination.value.pageSize })
    .then(res => {
      const page = res.data || {}
      tableData.value = page.list || []
      pagination.value.total = page.total || 0
      const { studentId, buildingId, roomId, status } = queryForm.value
      if (studentId) tableData.value = tableData.value.filter(it => it.studentId && it.studentId.toString().includes(studentId))
      if (buildingId) tableData.value = tableData.value.filter(it => it.buildingId === buildingId)
      if (roomId) tableData.value = tableData.value.filter(it => it.roomId === roomId)
      if (status) tableData.value = tableData.value.filter(it => it.status === status)
    })
    .catch(err => ElMessage.error(err.message || '获取数据失败'))
    .finally(() => loading.value = false)
}

const handleSizeChange = (val) => { pagination.value.pageSize = val; pagination.value.currentPage = 1; getData() }
const handleCurrentChange = (val) => { pagination.value.currentPage = val; getData() }
const handleSelectionChange = (rows) => { selectedRows.value = rows }

const reset = () => {
  formData.value = { id: '', studentId: null, buildingId: null, roomId: null, bedNo: '', checkInDate: '', checkOutDate: '', operatorId: null, status: '入住中', remark: '' }
}
const cancel = () => { dialogFormVisible.value = false; reset() }

const handleAddModel = () => { dialogFormVisible.value = true; title.value = '办理入住'; reset() }
const handleEdit = (row) => { dialogFormVisible.value = true; title.value = '编辑记录'; formData.value = { ...row } }

const submitForm = () => {
  formRef.value.validate(valid => {
    if (!valid) return
    const api = formData.value.id ? updateCheckIn : addCheckIn
    // 从本地存储获取当前登录用户，优先使用其ID作为操作员ID
    let currentUserId = null
    try {
      const userStr = localStorage.getItem('user')
      currentUserId = userStr ? JSON.parse(userStr)?.id ?? null : null
    } catch (e) {
      currentUserId = null
    }
    const payload = {
      ...formData.value,
      // 将空字符串规范为 null
      checkInDate: formData.value.checkInDate || null,
      checkOutDate: formData.value.checkOutDate || null,
      operatorId: (currentUserId != null ? currentUserId : (formData.value.operatorId || null)),
      remark: (formData.value.remark === '' ? null : formData.value.remark)
    }
    api(payload).then(res => {
      if (res.code === 200) { ElMessage.success(res.message); cancel(); getData() } else { ElMessage.error(res.message) }
    }).catch(err => ElMessage.error(err.message))
  })
}

const handleDelete = (id) => {
  ElMessageBox.confirm('此操作将删除该记录, 是否继续?', '提示', { type: 'warning' })
    .then(() => deleteCheckIn(id))
    .then(res => { if (res.code === 200) { ElMessage.success(res.message); getData() } else { ElMessage.error(res.message) } })
    .catch(() => {})
}

const handleBatchDelete = () => {
  if (!selectedRows.value.length) return ElMessage.warning('请至少选择一条数据')
  const ids = selectedRows.value.map(r => r.id)
  ElMessageBox.confirm(`此操作将永久删除选中的 ${ids.length} 条数据, 是否继续?`, '提示', { type: 'warning' })
    .then(() => batchDeleteCheckIn(ids))
    .then(res => { if (res.code === 200) { ElMessage.success(res.message); getData(); multipleTableRef.value?.clearSelection() } else { ElMessage.error(res.message) } })
    .catch(() => {})
}

const onBuildingChange = (val) => {
  formData.value.roomId = null
  loadRoomsByBuilding(val)
}

const handleSearch = () => { pagination.value.currentPage = 1; getData() }
const handleResetQuery = () => { queryForm.value = { studentId: '', buildingId: null, roomId: null, status: '' }; getData() }

// 导入成功回调
const importExcelSuccess = (res) => {
  if (res && res.code === 200) {
    ElMessage.success(res.message || '导入成功')
    getData()
  } else {
    ElMessage.error((res && res.message) || '导入失败')
  }
}

// 导出
const handleExportExcel = () => {
  window.open('http://localhost:8080/api/checkIn/export')
}

// 状态展示为标签
const getCheckinStatusType = (s) => {
  if (s === '入住中') return 'success'
  if (s === '已退宿') return 'info'
  return ''
}
</script>


<template>
  <div class="card">
    <div class="toolbar">
      <el-input v-model="queryForm.studentId" placeholder="学生ID" style="width: 180px" clearable/>
      <el-select v-model="queryForm.buildingId" placeholder="选择楼宇" style="width: 220px" filterable clearable @change="val => loadRoomsByBuilding(val)">
        <el-option v-for="b in buildingOptions" :key="b.value" :label="b.label" :value="b.value"/>
      </el-select>
      <el-select v-model="queryForm.roomId" placeholder="选择房间" style="width: 220px" filterable clearable>
        <el-option v-for="r in roomOptions" :key="r.value" :label="r.label" :value="r.value"/>
      </el-select>
      <el-select v-model="queryForm.status" placeholder="状态" style="width: 160px" clearable>
        <el-option label="入住中" value="入住中"/>
        <el-option label="已退宿" value="已退宿"/>
      </el-select>
      <el-button type="primary" :icon="Refresh" @click="handleSearch">查询</el-button>
      <el-button @click="handleResetQuery">重置</el-button>
    </div>
    <div class="actions">
      <el-button type="primary" :icon="Plus" @click="handleAddModel">办理入住</el-button>
      <el-upload :action="'http://localhost:8080/api/checkIn/import'" :on-success="importExcelSuccess" :show-file-list="false" class="upload-excel">
        <el-button type="success" :icon="Download">导入</el-button>
      </el-upload>
      <el-button type="info" :icon="Upload" @click="handleExportExcel">导出</el-button>
      <el-button type="danger" :icon="Delete" @click="handleBatchDelete">批量删除</el-button>
    </div>

    <el-table :data="tableData" border stripe size="small" fit highlight-current-row v-loading="loading" @selection-change="handleSelectionChange" ref="multipleTableRef">
      <el-table-column type="selection" width="50"/>
      <el-table-column label="楼宇" width="200">
        <template #default="scope">{{ buildingLabelMap[scope.row.buildingId] || scope.row.buildingId }}</template>
      </el-table-column>
      <el-table-column label="房间" width="160">
        <template #default="scope">{{ roomLabelMap[scope.row.roomId] || scope.row.roomId }}</template>
      </el-table-column>
      <el-table-column prop="studentId" label="学生ID" width="120"/>
      <el-table-column prop="bedNo" label="床位号" width="100"/>
      <el-table-column prop="checkInDate" label="入住日期" width="140"/>
      <el-table-column prop="checkOutDate" label="退宿日期" width="140"/>
      <el-table-column label="状态" width="100">
        <template #default="scope">
          <el-tag :type="getCheckinStatusType(scope.row.status)">{{ scope.row.status || '-' }}</el-tag>
        </template>
      </el-table-column>
      <el-table-column prop="remark" label="备注" show-overflow-tooltip/>
      <el-table-column label="操作" width="260" fixed="right">
        <template #default="scope">
          <el-button size="small" @click="handleEdit(scope.row)">编辑</el-button>
          <el-button size="small" type="danger" @click="handleDelete(scope.row.id)">删除</el-button>
          <el-button size="small" type="warning" @click="() => checkout(scope.row.id).then(res => { if (res.code===200){ElMessage.success(res.message); getData()} else {ElMessage.error(res.message)} })">退宿</el-button>
        </template>
      </el-table-column>
    </el-table>

    <div class="pager">
      <el-pagination
        v-model:current-page="pagination.currentPage"
        v-model:page-size="pagination.pageSize"
        :page-sizes="[5,10,20,50]"
        layout="total, sizes, prev, pager, next, jumper"
        :total="pagination.total"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
      />
    </div>

    <el-dialog v-model="dialogFormVisible" :title="title" width="600px" @close="reset">
      <el-form ref="formRef" :model="formData" :rules="rules" label-width="100px" size="small">
        <el-form-item label="学生ID" prop="studentId">
          <el-input v-model="formData.studentId" placeholder="请输入学生ID"/>
        </el-form-item>
        <el-form-item label="所属楼宇" prop="buildingId">
          <el-select v-model="formData.buildingId" placeholder="请选择楼宇" filterable clearable @change="onBuildingChange">
            <el-option v-for="b in buildingOptions" :key="b.value" :label="b.label" :value="b.value"/>
          </el-select>
        </el-form-item>
        <el-form-item label="房间" prop="roomId">
          <el-select v-model="formData.roomId" placeholder="请选择房间" filterable clearable>
            <el-option v-for="r in roomOptions" :key="r.value" :label="r.label" :value="r.value"/>
          </el-select>
        </el-form-item>
        <el-form-item label="床位号" prop="bedNo">
          <el-input v-model="formData.bedNo" placeholder="如 1-1"/>
        </el-form-item>
        <el-form-item label="入住日期">
          <el-date-picker v-model="formData.checkInDate" type="date" placeholder="选择日期" style="width: 100%"/>
        </el-form-item>
        <el-form-item label="退宿日期">
          <el-date-picker v-model="formData.checkOutDate" type="date" placeholder="选择日期" style="width: 100%"/>
        </el-form-item>
        <el-form-item label="备注">
          <el-input type="textarea" v-model="formData.remark" rows="3" placeholder="可选"/>
        </el-form-item>
      </el-form>
      <template #footer>
        <el-button @click="cancel">取消</el-button>
        <el-button type="primary" @click="submitForm">确定</el-button>
      </template>
    </el-dialog>
  </div>
</template>

<style scoped>
.card { background: #fff; padding: 16px; border-radius: 8px; }
.toolbar { margin-bottom: 8px; display: flex; align-items: center; flex-wrap: wrap; gap: 10px; }
.actions { margin-bottom: 12px; display: flex; align-items: center; gap: 10px; }
.pager { margin-top: 12px; display: flex; justify-content: flex-end; }
.upload-excel{ display: inline-block; }
</style>